<template>
  <li>
    <label v-show="editId !== todo.id">
      <!-- 注意: 这里可以使用v-model.也可以实现功能.但是不建议写v-model.因为这样属于修改props数据 -->
      <input type="checkbox" :checked="todo.isDone" @click="handle" />
      <span :class="classObj">{{ todo.todoName }}</span>
    </label>
    <input
      v-show="editId === todo.id"
      type="text"
      :id="todo.id"
      @keyup.enter="setTodoNameHandle"
    />
    <button class="btn btn-danger" @click="delHandle">删除</button>
    <button class="btn btn-edit" @click="editHandle">
      {{ editId !== todo.id ? '编辑' : '取消' }}
    </button>
  </li>
</template>

<script>
import PubSub from 'pubsub-js'
export default {
  // 接收props数据
  props: ['todo', 'editId'],
  data() {
    return {
      classObj: {
        done: this.todo.isDone,
      },
    }
  },
  methods: {
    // 修改任务状态
    handle() {
      // 通知app,修改指定任务数据的isDone
      PubSub.publish('update', this.todo.id)
    },
    // 删除一条任务
    delHandle() {
      //通知app组件删除一条数据
      PubSub.publish('del', this.todo.id)
    },
    // 编辑按钮的事件处理函数
    editHandle() {
      // 通知app修改editId的值
      PubSub.publish(
        'updateEditId',
        this.editId !== this.todo.id ? this.todo.id : undefined
      )
      // $nextTick是修改当前组件或vue实例自己的数据,模板更新完毕之后触发.而我们当前的需求是修改别的组件的数据,所以$nextTick没什么用
      // this.$nextTick(() => {
      // dom渲染完毕之后执行这个函数
      // 获取编辑文本框的dom对象
      // 此时能够获取到编辑文本框的dom对象,完全是因为使用了v-show
      const inp = document.getElementById(this.todo.id + '')
      inp.value = this.todo.todoName
      // })
    },
    // 编辑文本框按下回车键的事件处理函数
    setTodoNameHandle(e) {
      const value = e.target.value.trim()
      // 判断用户修改的内容是否为空
      if (!value) return

      // 通知app修改指定任务对象的todoName
      PubSub.publish('setTodoName', { todoName: value, id: this.todo.id })
    },
  },
  watch: {
    // 监听todo,监听到todo的数据发生变化了,然后修改classObj
    todo: {
      deep: true,
      handler() {
        this.classObj.done = this.todo.isDone
      },
    },
  },
}
</script>

<style>
/*item*/
li {
  list-style: none;
  height: 36px;
  line-height: 36px;
  padding: 0 5px;
  border-bottom: 1px solid #ddd;
}

li label {
  display: flex;
  align-items: center;
  float: left;
  cursor: pointer;
}

li label span.done {
  text-decoration: line-through;
  color: #ccc;
}

li label li input {
  vertical-align: middle;
  margin-right: 6px;
  position: relative;
  top: -1px;
}

li button {
  float: right;
  display: none;
  margin-top: 3px;
}

li:before {
  content: initial;
}

li:last-child {
  border-bottom: none;
}
</style>
